/*
 * Copyright (C) 2010 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

import com.mol.market.Constants;
import com.mol.market.Session;
import com.mol.market.common.util.CashbackManager.CashbackTask;
import com.mol.market.common.vo.BuyLog;
import com.mol.market.common.vo.CardsVerification;
import com.mol.market.common.vo.CardsVerifications;
import com.mol.market.common.vo.LogEntity;
import com.mol.market.common.vo.UpgradeInfo;
import com.mol.market.fanli.ui.TaskInformationActivity.RebateTask;

/**
 * 关于Content Provider的工具类
 * 
 * @author andrew
 * @date 2011-4-26
 * @since Version 0.7.0
 */
public class DBUtils {
    
    /**
     * 数据库操作回调函数 
     *
     * @param <T> 数据库操作结果
     */
    public static class DbOperationResultListener<T> {
        
        protected void onQueryResult(T result) {
        }
        
        protected void onInsertResult(T result) {
        }
        
    }
    
    /**
     * 判断是否CPA产品
     */
    public static boolean isCpaProduct(Context context, String pkgName) {
        Cursor c = context.getContentResolver().query(
                MarketProvider.CASHBACK_CONTENT_URI, 
                null,
                MarketProvider.COLUMN_PACKAGE_NAME + " = ? ", 
                new String[] { pkgName },
                null);
        try {
            if (c != null && c.moveToFirst()) {
                return true;
            }
            return false;
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }
    
    /**
     * 插入返利任务
     */
    public static void insertOrUpdateTask(Context context, CashbackTask task) {

        ContentValues value = new ContentValues();
        value.put(MarketProvider.COLUMN_PACKAGE_NAME, task.packageName);
        
        if (task.taskId != 0) {
          value.put(MarketProvider.COLUMN_TASK_ID, task.taskId);
        }
        if (task.status != 0) {
          value.put(MarketProvider.COLUMN_STATUS, task.status);
        }
        if (task.source != 0) {
          value.put(MarketProvider.COLUMN_PACKAGE_SOURCE, task.source);
        }
        
        if (isCpaProduct(context, task.packageName)) {
            context.getContentResolver().update(
                    MarketProvider.CASHBACK_CONTENT_URI, value,
                    MarketProvider.COLUMN_PACKAGE_NAME + " = ? ",
                    new String[] { task.packageName });
        } else {
            context.getContentResolver().insert(
                    MarketProvider.CASHBACK_CONTENT_URI, value);
        }
    }
    
    /**
     * 获取所有任务
     */

    public static HashMap<String, CashbackTask> queryAllTask(Context context) {
        Cursor c = context.getContentResolver().query(
                MarketProvider.CASHBACK_CONTENT_URI, null, 
                MarketProvider.COLUMN_PACKAGE_SOURCE + " = ? AND " +
                MarketProvider.COLUMN_STATUS + " != ?",
                new String[] { String.valueOf(CashbackTask.SOURCE_REBATE),
                               String.valueOf(RebateTask.STATUS_REBATED)},
                null);
        try {
            if (c == null) {
                return null;
            }

            HashMap<String, CashbackTask> tasks = new HashMap<String, CashbackTask>();

            while (c.moveToNext()) {
                CashbackTask task = new CashbackTask();
                task.packageName = c.getString(c
                        .getColumnIndex(MarketProvider.COLUMN_PACKAGE_NAME));
                task.taskId = c.getLong(c
                        .getColumnIndex(MarketProvider.COLUMN_TASK_ID));
                task.status = c.getInt(c
                        .getColumnIndex(MarketProvider.COLUMN_STATUS));
                tasks.put(task.packageName, task);
            }
            return tasks;
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }
    

    public static ArrayList<CashbackTask> queryInstallation(Context context) {
      Cursor c = context.getContentResolver().query(
          MarketProvider.CASHBACK_CONTENT_URI, null,
          MarketProvider.COLUMN_STATUS + " = ? ",
          new String[] { String.valueOf(RebateTask.STATUS_INSTALLED) }, null);
      try {
        if (c == null) {
          return null;
        }
  
        ArrayList<CashbackTask> tasks = new ArrayList<CashbackTask>();
  
        while (c.moveToNext()) {
          CashbackTask task = new CashbackTask();
          task.packageName = c.getString(c
              .getColumnIndex(MarketProvider.COLUMN_PACKAGE_NAME));
          task.source = c.getInt(c
              .getColumnIndex(MarketProvider.COLUMN_PACKAGE_SOURCE));
          tasks.add(task);
        }
        return tasks;
      } finally {
        if (c != null) {
          c.close();
        }
      }
    }
    
    /**
     * 删除已返利任务
     */
    public static void delTask(Context context, String pkgName) {
        context.getContentResolver().delete(MarketProvider.CASHBACK_CONTENT_URI,
            MarketProvider.COLUMN_PACKAGE_NAME + "= ? ",
            new String[]{ pkgName });
    }
    
    
    /**
     * 清除推送条目
     * 
     * @param nid
     *            推送条目ID
     */
    public static void delPushItem(Context context, String nid) {
        new AsyncQueryHandler(context.getContentResolver()) {
        }.startDelete(0, null, MarketProvider.PUSH_CONTENT_URI, MarketProvider.COLUMN_NID + " = '"
                + nid + "'", null);
    }
    
    /**
     * 插入新的推送条目
     * @param context
     * @param items
     */
    public static void insertPushItems(Context context, ArrayList<HashMap<String, Object>> items) {

        ContentValues[] values = new ContentValues[items.size()];
        int i = 0;
        for (HashMap<String, Object> item : items) {
            ContentValues value = new ContentValues();
            value.put(MarketProvider.COLUMN_P_ID, (String) item.get(Constants.KEY_ID));
            value.put(MarketProvider.COLUMN_TITLE,
                    (String) item.get(Constants.KEY_NOTIFICATION_RECOMMEND_TITLE));
            value.put(MarketProvider.COLUMN_DESCRPTION,
                    (String) item.get(Constants.KEY_DESCRIPTION));
            value.put(MarketProvider.COLUMN_UPDATE_TIME,
                    (String) item.get(Constants.KEY_UPDATE_TIME));
            value.put(MarketProvider.COLUMN_NID,
                    (String) item.get(Constants.KEY_NOTIFICATION_RECOMMEND_NID));
            value.put(MarketProvider.COLUMN_RULE,
                    (String) item.get(Constants.KEY_NOTIFICATION_RECOMMEND_RULE));
            value.put(MarketProvider.COLUMN_URL,
                    (String) item.get(Constants.KEY_NOTIFICATION_URL));
            value.put(MarketProvider.COLUMN_CHECKED, 0);
            values[i++] = value;
        }
        Session.get(context).setNotificationTime(
                values[values.length - 1].getAsString(MarketProvider.COLUMN_UPDATE_TIME));
        context.getContentResolver().bulkInsert(MarketProvider.PUSH_CONTENT_URI, values);
    }
    
    /**
     * 标记产品已经被检查过
     * @param context
     * @param uid
     */
    public static void markItemChecked(Context context, String nid) {

        ContentValues value = new ContentValues();
        value.put(MarketProvider.COLUMN_CHECKED, 1);

        new AsyncQueryHandler(context.getContentResolver()) {
        }.startUpdate(0, null, MarketProvider.PUSH_CONTENT_URI, value, MarketProvider.COLUMN_NID
                + " = '" + nid + "'", null);
    }
    
    /**
     * 查询推送的条目
     * @param context
     * @return
     */
    public static void queryPushItems(Context context,
            final DbOperationResultListener<ArrayList<HashMap<String, Object>>> listener) {
        
        AsyncQueryHandler handler = new AsyncQueryHandler(context.getContentResolver()) {

            @Override
            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
                if (cursor != null) {
                    int index = 0;
                    final ArrayList<HashMap<String, Object>> result = 
                        new ArrayList<HashMap<String, Object>>();
                    
                    while (cursor.moveToNext()) {

                        HashMap<String, Object> item = new HashMap<String, Object>();
                        item.put(Constants.KEY_ID,
                                cursor.getString(cursor.getColumnIndex(MarketProvider.COLUMN_P_ID)));
                        item.put(Constants.KEY_NOTIFICATION_RECOMMEND_TITLE, cursor
                                .getString(cursor.getColumnIndex(MarketProvider.COLUMN_TITLE)));
                        item.put(Constants.KEY_DESCRIPTION, cursor.getString(cursor
                                .getColumnIndex(MarketProvider.COLUMN_DESCRPTION)));
                        item.put(Constants.KEY_UPDATE_TIME, cursor.getString(cursor
                                .getColumnIndex(MarketProvider.COLUMN_UPDATE_TIME)));
                        item.put(Constants.KEY_NOTIFICATION_RECOMMEND_NID,
                                cursor.getString(cursor.getColumnIndex(MarketProvider.COLUMN_NID)));
                        item.put(Constants.KEY_NOTIFICATION_RECOMMEND_RULE,
                                cursor.getString(cursor.getColumnIndex(MarketProvider.COLUMN_RULE)));
                        item.put(Constants.KEY_NOTIFICATION_URL,
                                cursor.getString(cursor.getColumnIndex(MarketProvider.COLUMN_URL)));

                        result.add(item);
                        index++;
                    }
                    cursor.close();
                    listener.onQueryResult(result);
                }
            }
        };
        handler.startQuery(0, null, MarketProvider.PUSH_CONTENT_URI, null,
                MarketProvider.COLUMN_CHECKED + " = '0'", null, MarketProvider.COLUMN_NID + " ASC");
    }

    /**
     * 清除所有搜索历史
     * 
     * @param context
     *            Application Context
     */
    public static void clearSearchHistory(Context context) {
        new AsyncQueryHandler(context.getContentResolver()) {
        }.startDelete(0, null, MarketProvider.SEARCH_CONTENT_URI, null, null);
    }

    /**
     * 添加搜索历史关键词
     * 
     * @param context
     *            Application Context
     * @param keyword
     *            搜索关键词
     */
    public static void addSearchItem(Context context, String keyword) {
        ContentValues values = new ContentValues();
        values.put(MarketProvider.COLUMN_SEARCH_KEY_WORD, keyword);
        new AsyncQueryHandler(context.getContentResolver()) {
        }.startInsert(0, null, MarketProvider.SEARCH_CONTENT_URI, values);
    }
    
    /**
     * 获得搜索历史关键词（最多20条数据）
     * 
     * @return 搜索关键词列表 ArrayList<String>
     */
    public static void querySearchHistory(Context context,
            final DbOperationResultListener<ArrayList<String>> listener) {

        final ArrayList<String> result = new ArrayList<String>();
        AsyncQueryHandler handler = new AsyncQueryHandler(context.getContentResolver()) {

            @Override
            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
                if (cursor != null) {
                    final int fieldIndex = cursor
                            .getColumnIndex(MarketProvider.COLUMN_SEARCH_KEY_WORD);
                    int index = 0;
                    while (cursor.moveToNext()) {

                        if (index > 19) {
                            break;
                        }
                        result.add(cursor.getString(fieldIndex));
                        index++;
                    }
                    cursor.close();
                    listener.onQueryResult(result);
                }
            }
        };
        handler.startQuery(0, null, MarketProvider.SEARCH_CONTENT_URI, null, null, null,
                MarketProvider.COLUMN_ID + " DESC");
    }

    /**
     * 添加购买记录
     */
    public static void insertBuyLog(Context context, BuyLog log) {
        ContentValues values = new ContentValues();
        log.onAddToDatabase(values);
        context.getContentResolver().insert(MarketProvider.BUY_CONTENT_URI, values);
    }

    /**
     * 查询是否已经购买
     */
    public static void isBought(Context context, String pid,
            final DbOperationResultListener<Boolean> listener) {

        new AsyncQueryHandler(context.getContentResolver()) {
            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
                if (cursor != null) {

                    if (cursor.getCount() > 0) {
                        listener.onQueryResult(true);
                    } else {
                        listener.onQueryResult(false);
                    }
                    cursor.close();
                }
            };
        }.startQuery(0, null, MarketProvider.BUY_CONTENT_URI, new String[] {
                MarketProvider.COLUMN_P_ID, MarketProvider.COLUMN_P_PACKAGE_NAME },
                MarketProvider.COLUMN_P_ID + " = '" + pid + "'", null, null);
    }

    /**
     * 刷新本地已购买列表
     */
    public static void updateBuyedList(Context context, List<BuyLog> buyLogList) {
        final ContentResolver cr = context.getContentResolver();
        cr.delete(MarketProvider.BUY_CONTENT_URI, null, null);
        ContentValues values = null;
        for (BuyLog log : buyLogList) {
            values = new ContentValues();
            log.onAddToDatabase(values);
            cr.insert(MarketProvider.BUY_CONTENT_URI, values);
        }
    }

    /**
     * 获取已经购买的应用列表
     */

    public static List<BuyLog> getUpdateBuyedList(Context context) {
        List<BuyLog> buyLogList = new ArrayList<BuyLog>();
        BuyLog log = null;
        final ContentResolver cr = context.getContentResolver();
        Cursor c = cr.query(MarketProvider.BUY_CONTENT_URI, null, null, null, null);
        if (c != null) {
            if (c.getCount() > 0 && c.moveToFirst()) {
                do {
                    log = new BuyLog();
                    log.pId = c.getString(c.getColumnIndex(MarketProvider.COLUMN_P_ID));
                    log.packageName = c.getString(c
                            .getColumnIndex(MarketProvider.COLUMN_P_PACKAGE_NAME));
                    buyLogList.add(log);
                } while (c.moveToNext());
            }
            c.close();
        }
        return buyLogList;
    }

    public static void updataCardsVerification(Context context, List<CardsVerification> cards) {
        final ContentResolver cr = context.getContentResolver();
        cr.delete(MarketProvider.CARD_CONTENT_URI, null, null);
        for (CardsVerification card : cards) {
            ContentValues values = new ContentValues();
            card.onAddToDatabase(values);
            cr.insert(MarketProvider.CARD_CONTENT_URI, values);
        }
    }


    public static CardsVerifications getAllCardsVerification(Context context) {
        CardsVerifications cards = new CardsVerifications();
        CardsVerification card = null;
        final ContentResolver cr = context.getContentResolver();
        String selection = null;
        String[] selectionArgs = null;
        Cursor c = cr.query(MarketProvider.CARD_CONTENT_URI, null, selection, selectionArgs, null);
        if (c != null) {
            if (c.getCount() > 0) {
                c.moveToFirst();
                do {
                    card = new CardsVerification();
                    card.name = c.getString(c.getColumnIndex(MarketProvider.COLUMN_CARD_NAME));
                    card.pay_type = c.getString(c
                            .getColumnIndex(MarketProvider.COLUMN_CARD_PAY_TYPE));
                    card.accountNum = c.getInt(c
                            .getColumnIndex(MarketProvider.COLUMN_CARD_ACCOUNTNUM));
                    card.passwordNum = c.getInt(c
                            .getColumnIndex(MarketProvider.COLUMN_CARD_PASSWORDNUM));
                    card.credit = c.getString(c.getColumnIndex(MarketProvider.COLUMN_CARD_CREDIT));
                    cards.cards.add(card);
                } while (c.moveToNext());
            }
            c.close();
        }
        return cards;
    }

    /**
     * 添加可更新应用
     * 
     * @param context
     *            Application Context
     * @param item
     *            API返回的可更新应用列表
     */
    public static int addUpdateProduct(Context context, HashMap<String, UpgradeInfo> list) {

        Cursor cursor = context.getContentResolver().query(MarketProvider.UPDATE_CONTENT_URI, null,
                null, null, null);

        HashMap<String, UpgradeInfo> dbData = null;
        if (cursor != null) {
            dbData = new HashMap<String, UpgradeInfo>();
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                UpgradeInfo info = new UpgradeInfo();
                info.pkgName = cursor.getString(cursor
                        .getColumnIndex(MarketProvider.COLUMN_P_PACKAGE_NAME));
                info.versionCode = cursor.getInt(cursor
                        .getColumnIndex(MarketProvider.COLUMN_P_NEW_VERSION_CODE));
                info.update = cursor.getInt(cursor.getColumnIndex(MarketProvider.COLUMN_P_IGNORE));
                dbData.put(info.pkgName, info);
            }
            cursor.close();
        }

        int result = 0;
        if (dbData != null) {
            
            int i = 0;
            ContentValues[] values = new ContentValues[list.size()];
            for (UpgradeInfo info : list.values()) {
                // 如果用户忽略了此版本的更新，不应该再次提醒
                if (dbData.containsKey(info.pkgName)) {
                    UpgradeInfo dbInfo = dbData.get(info.pkgName);
                    if (info.versionCode <= dbInfo.versionCode && dbInfo.update == 1) {
                        // 用户忽略了此更新
                        info.update = 1;
                    } else {
                        result++;
                    }
                } else {
                    // 2011/8/17 BUG 2344
                    result++;
                }
                
                values[i++] = info.getContentValues();
            }
            
            context.getContentResolver().delete(MarketProvider.UPDATE_CONTENT_URI, null, null);
            context.getContentResolver().bulkInsert(MarketProvider.UPDATE_CONTENT_URI, values);
        }

        if (result > 0) {
            Session session = Session.get(context);
            session.setUpdateList();
            session.setUpgradeNumber(result);
        }
        
        return result;
    }

    /**
     * 获取更新应用的签名MD5
     */
    public static String getUpdateRsaMd5(Context context, String packageName) {
        final ContentResolver cr = context.getContentResolver();
        String[] projection = new String[] { MarketProvider.COLUMN_P_SIGNATURE };
        String selection = MarketProvider.COLUMN_P_PACKAGE_NAME + " = ? ";
        String[] selectionArgs = new String[] { packageName };
        Cursor cursor = cr.query(MarketProvider.UPDATE_CONTENT_URI, projection, selection,
                selectionArgs, null);

        if (cursor != null) {
            cursor.close();
            return cursor.getString(0);
        }
        return "";
    }

    /**
     * 已经更新，删除项目
     * 
     * @param context
     * @param packageName
     */
    public static void removeUpgradable(Context context, final Session session, final String packageName) {
        String selection = MarketProvider.COLUMN_P_PACKAGE_NAME + " = ? ";
        String[] selectionArgs = new String[] { packageName };
        new AsyncQueryHandler(context.getContentResolver()) {
            protected void onDeleteComplete(int token, Object cookie, int result) {
                if (result > 0) {
                    session.getUpdateList().remove(packageName);
                    // 更新可升级应用数标识
                    session.setUpgradeNumber(session.getUpgradeNumber() - 1);
                }
                
            };
        }.startDelete(0, null, MarketProvider.UPDATE_CONTENT_URI, selection, selectionArgs);
    }

    /**
     * 忽略此版本的更新
     */
    public static void ignoreUpdate(final Context context, final String packageName) {
        ContentValues values = new ContentValues();
        String selection = MarketProvider.COLUMN_P_PACKAGE_NAME + " = ? ";
        String[] selectionArgs = new String[] { packageName };
        values.put(MarketProvider.COLUMN_P_IGNORE, 1);

        new AsyncQueryHandler(context.getContentResolver()) {
            @Override
            protected void onUpdateComplete(int token, Object cookie, int result) {
                Session.get(context).removeUpdateItem(packageName);
            }
        }.startUpdate(0, null, MarketProvider.UPDATE_CONTENT_URI, values, selection,
                selectionArgs);
    }

    /**
     * 查询可更新应用
     */

    public static ConcurrentHashMap<String, UpgradeInfo> queryUpdateProduct(Context context) {

        ConcurrentHashMap<String, UpgradeInfo> result = new ConcurrentHashMap<String, UpgradeInfo>();
        String selection = MarketProvider.COLUMN_P_IGNORE + " = ? ";
        String[] selectionArgs = new String[] { "0" };
        Cursor cursor = context.getContentResolver().query(MarketProvider.UPDATE_CONTENT_URI, null,
                selection, selectionArgs, null);
        if (cursor != null) {
            if (cursor.getCount() > 0) {
                while (cursor.moveToNext()) {
                    UpgradeInfo info = new UpgradeInfo();
                    info.pid = cursor.getString(cursor.getColumnIndex(MarketProvider.COLUMN_P_ID));
                    info.pkgName = cursor.getString(cursor
                            .getColumnIndex(MarketProvider.COLUMN_P_PACKAGE_NAME));
                    info.versionName = cursor.getString(cursor
                            .getColumnIndex(MarketProvider.COLUMN_P_NEW_VERSION_NAME));
                    info.versionCode = cursor.getInt(cursor
                            .getColumnIndex(MarketProvider.COLUMN_P_NEW_VERSION_CODE));
                    info.signature = cursor.getString(cursor
                            .getColumnIndex(MarketProvider.COLUMN_P_SIGNATURE));
                    result.put(info.pkgName, info);
                }
            }
            cursor.close();
        }
        return result;
    }

    /**
     * 清除所有可更新记录
     */
    public static int clearUpdateProduct(Context context) {
        return context.getContentResolver().delete(MarketProvider.UPDATE_CONTENT_URI, null, null);
    }

    /**
     * 插入新的日志
     */
    public static Uri insertLog(Context context, LogEntity entity) {
        ContentValues values = new ContentValues();
        values.put(MarketProvider.COLUMN_CONTENT, entity.getLogContent());
        values.put(MarketProvider.COLUMN_MODULE, entity.module);
        values.put(MarketProvider.COLUMN_LEVEL, entity.level);
        values.put(MarketProvider.COLUMN_NETWORK, entity.network);
        values.put(MarketProvider.COLUMN_TIME, entity.createTime);
        return context.getContentResolver().insert(MarketProvider.LOG_CONTENT_URI, values);
    }


    public static ArrayList<LogEntity> submitLogs(Context context, String module, int level) {
        String selection = MarketProvider.COLUMN_LEVEL + " >= '" + level + "' AND "
                + MarketProvider.COLUMN_MODULE + " == '" + module + "'";
        Cursor c = context.getContentResolver().query(MarketProvider.LOG_CONTENT_URI, null,
                selection, null, null);
        if (c != null) {
            ArrayList<LogEntity> list = new ArrayList<LogEntity>();
            for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
                LogEntity entity = new LogEntity(context, module, level);
                entity.module = module;
                entity.level = level;
                entity.network = c.getString(c.getColumnIndex(MarketProvider.COLUMN_NETWORK));
                entity.setLogContent(c.getString(c.getColumnIndex(MarketProvider.COLUMN_CONTENT)));
                entity.createTime = c.getInt(c.getColumnIndex(MarketProvider.COLUMN_TIME));
                list.add(entity);
            }
            c.close();
            return list;
        }
        return null;
    }

    public static void delLogs(Context context, String module, int level) {
        String selection = MarketProvider.COLUMN_LEVEL + " >= '" + level + "' AND "
                + MarketProvider.COLUMN_MODULE + " == '" + module + "'";
        context.getContentResolver().delete(MarketProvider.LOG_CONTENT_URI, selection, null);
    }
}
